package net.jueb.protoServer.handler;
import java.util.concurrent.ConcurrentHashMap;
import net.jueb.protoServer.handler.dispatcher.MessageDispatcherHandler;
import net.jueb.protoServer.message.mapping.MessageMapping;
import net.jueb.protoServer.portService.PortService;
import net.jueb.protoServer.portService.PortService.PortType;
import net.jueb.protoServer.protocol.PortProtocol;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

/**
 * 端口服务初始化类,实现匹配端口服务和应用协议
 * @author Administrator
 */
public final class TcpServicePortInitializer extends ServicePortInitializer<SocketChannel>{
	
	protected static final InternalLogger log = InternalLoggerFactory.getInstance(TcpServicePortInitializer.class);
	/**
	 * 所有线程公用
	 */
	protected final ConcurrentHashMap<Integer,PortService<?>> portServices;
	
	
	public TcpServicePortInitializer(ConcurrentHashMap<Integer, PortService<?>> portServices) {
		this.portServices=portServices;
	}
	
	@Override
	public final PortType getPortType() {
		return PortType.TCP;
	}
	
	@Override
	protected final void initChannel(SocketChannel channel) throws Exception {
		int port=channel.localAddress().getPort();
		log.debug("本地端口:"+port+",客户端连接通道初始化:"+channel.remoteAddress().toString());
		PortService<?> ps=portServices.get(port);
		if(ps!=null && port==ps.getPort() && getPortType()==ps.getPortType())
		{//如果存在对应端口服务，且端口协议正确
			applyProtocol(channel,ps.getPortProtocol());
			log.debug("端口协议初始化完成!");
		}else
		{
			log.error("端口"+port+"未匹配到端口服务");
		}
	}
	/**
	 * 在匹配到端口服务后调用该方法
	 * 应用通道协议
	 * @param protocol
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void applyProtocol(SocketChannel channel,PortProtocol<?> protocol)
	{
		channel.pipeline().addLast(protocol.getMessageUnPackHandler());
		channel.pipeline().addLast(protocol.getMessageDecoderHandler());
		channel.pipeline().addLast(protocol.getMessagePackHandler());
		channel.pipeline().addLast(protocol.getMessageEncoderHandler());
		MessageMapping mapping=protocol.getMessageMapping();
		MessageDispatcherHandler dispatcher=protocol.getMessageDispatcher();
		if(dispatcher!=null)
		{//定义分发器使用的映射器
			dispatcher.setMapping(mapping);
			channel.pipeline().addLast(dispatcher);
		}
	}

}
